﻿namespace Nop.Plugin.Payments.UsaEpay
{
    #region

    using Nop.Core.Domain.Payments;
    using Nop.Services.Payments;

    #endregion

    /// <summary>
    /// The transaction response processor.
    /// </summary>
    public class TransactionResponseProcessor
    {
        /// <summary>
        /// The process transaction.
        /// </summary>
        /// <param name="transactionResponse">
        /// The transaction response.
        /// </param>
        /// <param name="processPaymentResult">
        /// The process payment result.
        /// </param>
        /// <returns>
        /// The <see cref="ProcessPaymentResult"/>.
        /// </returns>
        public static ProcessPaymentResult ProcessTransaction(TransactionResponse transactionResponse, ProcessPaymentResult processPaymentResult)
        {
            processPaymentResult.AllowStoringCreditCardNumber = false;

            switch (transactionResponse.ResultCode)
            {
                case TransactionResultCode.Approved:
                    processPaymentResult.AuthorizationTransactionCode = transactionResponse.AuthCode;
                    processPaymentResult.AvsResult = transactionResponse.AvsResultCode;
                    processPaymentResult.CaptureTransactionId = transactionResponse.RefNum;
                    processPaymentResult.CaptureTransactionResult = transactionResponse.Result;
                    processPaymentResult.NewPaymentStatus = PaymentStatus.Paid;
                    break;
                case TransactionResultCode.Declined:
                    processPaymentResult.AddError(string.Format("Payment was declined. {0}", transactionResponse.Error));
                    break;
                case TransactionResultCode.Error:
                    processPaymentResult.AddError(transactionResponse.Error);
                    break;
                case TransactionResultCode.Verification:
                    processPaymentResult.AddError(string.Format("Payment needs verification. {0}", transactionResponse.Error));
                    break;
            }

            return processPaymentResult;
        }

        /// <summary>
        /// The process refund.
        /// </summary>
        /// <param name="transactionResponse">
        /// The transaction response.
        /// </param>
        /// <param name="refundPaymentResult">
        /// The refund payment result.
        /// </param>
        /// <param name="isPartial">
        /// The is partial.
        /// </param>
        /// <returns>
        /// The <see cref="RefundPaymentResult"/>.
        /// </returns>
        public static RefundPaymentResult ProcessRefund(TransactionResponse transactionResponse, RefundPaymentResult refundPaymentResult, bool isPartial)
        {
            switch (transactionResponse.ResultCode)
            {
                case TransactionResultCode.Approved:
                    refundPaymentResult.NewPaymentStatus = isPartial ? PaymentStatus.PartiallyRefunded : PaymentStatus.Refunded;
                    break;
                case TransactionResultCode.Declined:
                    refundPaymentResult.AddError(string.Format("Refund was declined. {0}", transactionResponse.Error));
                    break;
                case TransactionResultCode.Error:
                    refundPaymentResult.AddError(transactionResponse.Error);
                    break;
                case TransactionResultCode.Verification:
                    refundPaymentResult.AddError(string.Format("Refund needs verification. {0}", transactionResponse.Error));
                    break;
            }

            return refundPaymentResult;
        }

        /// <summary>
        /// The process capture.
        /// </summary>
        /// <param name="transactionResponse">
        /// The transaction response.
        /// </param>
        /// <param name="capturePaymentResult">
        /// The capture payment result.
        /// </param>
        /// <returns>
        /// The <see cref="CapturePaymentResult"/>.
        /// </returns>
        public static CapturePaymentResult ProcessCapture(TransactionResponse transactionResponse, CapturePaymentResult capturePaymentResult)
        {
            switch (transactionResponse.ResultCode)
            {
                case TransactionResultCode.Approved:
                    capturePaymentResult.CaptureTransactionId = transactionResponse.RefNum;
                    capturePaymentResult.CaptureTransactionResult = transactionResponse.Result;
                    capturePaymentResult.NewPaymentStatus = PaymentStatus.Paid;
                    break;
                case TransactionResultCode.Declined:
                    capturePaymentResult.AddError(string.Format("Capture was declined. {0}", transactionResponse.Error));
                    break;
                case TransactionResultCode.Error:
                    capturePaymentResult.AddError(transactionResponse.Error);
                    break;
                case TransactionResultCode.Verification:
                    capturePaymentResult.AddError(string.Format("Capture needs verification. {0}", transactionResponse.Error));
                    break;
            }

            return capturePaymentResult;
        }
    }
}